 
					
						
					
				
				
					@robert-hh Another variant for measuring, which determines the difference between a minimal and maximal value over a window of samples, which should be at least a period of the signal to be tested, e.g. 20 ms for a 50Hz net. More simple than the last example, and immune to offset drifts. Still, the ADC is bad. The noise is a little bit lower if WiFi is switched off, but that only matters at small signals.
#
import math
import array
from machine import ADC, Timer, idle
samples = 600
freq = 50
_BUFFERSIZE = const(64)
#
# acquire ADC values at a fixed rate/s, which is given in
# the constructor. The second argument is the size
# of a ringbuffer, the third a string with the Pin name
#
class Acquire:
    def __init__(self, samples, buffersize, pin):
        self.put = 0
        self.get = 0
        self.buffersize = buffersize
        self.buffer = array.array("h", 0 for _ in range(self.buffersize))
        self.adc = ADC(bits=9)
        self.apin = self.adc.channel(pin=pin, attn=ADC.ATTN_11DB)
        self._alarm = Timer.Alarm(self.read_adc, 1/samples, periodic=True)
    def stop(self):
        self._alarm.cancel()
    def read_adc(self, alarm):
        self.buffer[self.put] = self.apin.value()
        self.put = (self.put + 1) % self.buffersize
    def next(self, period):
        vmin = 4096
        vmax = 0
        for _ in range(period):
            while self.get == self.put:
                idle()
            # calculate the moving average over the last three values:
            value = (self.buffer[self.get] +
                     self.buffer[(self.get - 1) % self.buffersize] +
                     self.buffer[(self.get - 2) % self.buffersize]) / 3
            vmin = min(value, vmin)
            vmax = max(value, vmax)
            self.get = (self.get + 1) % self.buffersize
        return vmax - vmin
#
# calculate a moving average
# The constructors argument is the window size
#
class Average:
    def __init__(self, size):
        self.size = size
        self.buffer = array.array("f", 0.0 for _ in range (size))
        self.put = 0
        self.sum = 0.0
    def avg(self, value):
        self.sum -= self.buffer[self.put]
        self.buffer[self.put] = value
        self.put = (self.put + 1) % self.size
        self.sum += value
        return self.sum / self.size
def run(noise=1.2):
    acq = Acquire(samples, _BUFFERSIZE, 'P20')
    avg_res = Average(freq)
    noise_sq = noise * noise
    try:
        i = 0
        while True:
            res = avg_res.avg(acq.next(samples/freq))
            i += 1
            if i == freq:
                # remove the noise floor
                res = math.sqrt(abs(res*res - noise_sq))
                print("{:6.2f} ".format(res/20.2))
                i = 0
    except KeyboardInterrupt:
        acq.stop()
        print("Handler stopped")
run()